#pragma once

#include <occmesh/api/chart.h>
#include <occmesh/api/feature.h>

/**
 * @file LSCMBuilder.h
 * @author xingyifan
 * @date 2023-08-18 17:49
 *
 * @description: LSCM 构建器
 */

class LSCMBuilder
{
  private:
    // 记录顶点状态
    struct VertexStates
    {
        bool fixed;
        int id;

        VertexStates(bool fixed = false, int id = -1) : fixed(fixed), id(id)
        {
        }
    };

    Mesh *m_mesh;
    FeatureMetric *m_metric;

    // 句柄，用于增加属性值
    OpenMesh::VPropHandleT<VertexStates> m_vertexStates;
    OpenMesh::FPropHandleT<int> m_faceId;

  public:
    LSCMBuilder(Mesh *mesh, FeatureMetric *metric = nullptr);
    ~LSCMBuilder();

    std::vector<Chart> Build();

  private:
    Mesh::Point OBB(const VertexList &vertices);
    int initializeIndex(const Chart &chart);
    void initializeSystem(const Chart &chart, SparseMatrix &A, SparseMatrix &fA, MatrixXx1 &fx);
    void projectFace(const Mesh::FaceHandle &face, Mesh::Point *pv, Mesh::VertexHandle *hv);
};
